export interface IParseResult {
  success: boolean;
  ast: IAst;
  cursorKeyPath: string[];
  nextMatchings: IMatching[];
  error: {
    token: IToken;
    reason: "wrong" | "incomplete";
    suggestions: IMatching[];
  };
  debugInfo: {
    tokens: IToken[];
    callVisiterCount: number;
    costs: {
      lexer: number;
      parser: number;
    };
  };
}

export interface IMatching {
  // loose not cost token, and result is fixed true of false.
  type: "string" | "loose" | "special";
  value: string | boolean;
}

export interface IToken {
  type: string;
  value: string;
  statement: string;
  index: number;
  position?: [number, number];
}

export type IAst = IToken | any;

export interface ITableParams {
  variant: string;
  tableInfo: ITableInfo;
}

export interface ITableInfo {
  tableName: IToken;
  cluster: IToken | null;
  database: IToken | null;
}

export interface ICompletionItem {
  label: string;
  kind?: number;
  sortText?: string;
  insertText?: string;
  filterText?: string;
  tableInfo?: ITableInfo;
  groupPickerName?: string;
  originFieldName?: string;
  detail?: string;
  documentation?: string;
}

export interface IStatement {
  type: "statement" | "identifier";
  variant: string;
}

export type ICursorInfo<T = {}> = {
  token: IToken;
  type: CursorType;
} & T;

export type CursorType =
  | "tableField"
  | "tableName"
  | "cluster"
  | "database"
  // | 'namespace'
  | "namespaceOne"
  | "functionName"
  | "tableFieldAfterGroup"
  | "columnType"
  | "charset"
  | "env"
  | "udfName";

export type IParserType =
  | "mysql"
  | "odps"
  | "blink"
  | "dsql"
  | "grail"
  | "emcsql";

export type IGetFieldsByTableName = (
  tableName: ITableInfo,
  inputValue: string | null,
  rootStatement: IStatement | null
) => Promise<ICompletionItem[]>;

export interface ISelectStatement extends IStatement {
  from: IFrom;
  result: IResult[];
  tableInfo: ITableInfo;
}

export interface IFrom extends IStatement {
  sources: ISource[];
  where?: any;
  group?: any;
  having?: any;
}

export interface IResult extends IStatement {
  name: IToken;
  alias: IToken;
}

export interface ISource extends IStatement {
  name: ITableInfo & IStatement;
  alias: IToken;
}

export type IStatements = IStatement[];

export type IDispose = () => void;
